#pragma once

#include "Comm.hpp"

#include <cstdio>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define CURRENTPATH "."
#define FILENAME "fifo"

class NamedFifo
{
private:
    // 删除命名管道
    void Destroy()
    {
        int n = unlink(_filename.c_str());
        if (n < 0)
            ERR_EXIT("unlink");
        printf("unlink fifo sueccess!\n");
    }

public:
    NamedFifo(const std::string &path, const std::string &name)
        : _path(path), _name(name)
    {
        _filename = _path + "/" + _name;
    }
    // 创建命名管道
    void Create()
    {
        int n = mkfifo(_filename.c_str(), 0666);
        if (n < 0)
            ERR_EXIT("mkfifo");
        printf("mkfifo sueccess!\n");
    }
    ~NamedFifo()
    {
        Destroy();
    }

private:
    std::string _path;
    std::string _name;
    std::string _filename;
};

class FileOper
{
private:
    void Close()
    {
        if (_fd > 0)
            close(_fd);
    }

public:
    FileOper(const std::string &path, const std::string &name)
        : _path(path), _name(name)
    {
        _filename = _path + "/" + _name;
    }
    // 以读方式打开
    void OpenForRead()
    {
        _fd = open(_filename.c_str(), O_RDONLY);
        if (_fd < 0)
            ERR_EXIT("open");
        printf("open for read success!, %d\n", _fd);
    }
    // 以写方式打开
    void OpenForWrite()
    {
        _fd = open(_filename.c_str(), O_WRONLY); //多了Int 这里就相当于你有定义了一个_fd了
        if (_fd < 0)
            ERR_EXIT("open");
        printf("open for write success!, %d\n", _fd);
    }
    // 从命名管道读取
    ssize_t Read()
    {
        char c;
        int n = read(_fd, &c, 1);
        if (n < 0)
            ERR_EXIT("read");
        return n;
    }
    // 写入命名管道
    ssize_t Write()
    {
        char c = 'c';
        ssize_t n = write(_fd, &c, 1);
        if (n < 0)
            ERR_EXIT("write");
        return n;
    }
    // 等待写入
    bool Wait()
    {
        ssize_t n = Read();
        if (n > 0)
        {
            printf("等待写入: %zd\n", n);
            return true;
        }
        else
            return false;
    }
    // 唤醒
    void WakeUp()
    {
        ssize_t n = Write();
        printf("尝试唤醒: %zd\n", n);
    }
    ~FileOper()
    {
    }

private:
    std::string _path;
    std::string _name;
    std::string _filename;
    int _fd;
};